package com.spzx.report.vectorTools;

// 导入JSON处理所需的类
import com.fasterxml.jackson.databind.ObjectMapper;
// 导入Apache HTTP客户端相关类，用于发送HTTP请求
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
// 导入Java基础类
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class PineconeUploadUtil {

    // 创建ObjectMapper实例，用于JSON序列化和反序列化
    static ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    /***
     * 通过集合上传，前期数据处理
     * @param list 待处理的数据列表，每个元素是一个Map，包含key_word和key_column
     * @param pineconeIndexKey Pinecone索引的API端点URL
     * @param pineconeKey Pinecone API密钥
     */
    public static void uploadListToPinecone(List<Map<String, Object>> list, String pineconeIndexKey, String pineconeKey) {
        // 用于暂存待上传的向量数据，每50条一批
        List<Map<String, Object>> batch = new ArrayList<>();
        // 记录处理的总行数
        int lineNum = 0;
        // 记录成功上传的数量
        int successCount = 0;
        // 记录失败的数量
        int failedCount = 0;

        String line; // 未使用的变量，可能是代码遗留


        // 遍历输入列表中的每个Map
        for (Map<String, Object> map : list) {
            // 从Map中获取关键词并去除首尾空格
            String cleanText = map.get("key_word").toString().trim();

            // 调用外部工具类将文本转换为向量表示
            float[] vector = SpzxEmbeddingTools.getEmbedding(cleanText).vector();

            // 检查向量是否有效（长度是否大于0）
            if (vector.length == 0) {
                System.err.println(" 向量化失败，跳过行 " + lineNum + ": " + cleanText);
                failedCount++;
                continue; // 跳过当前行，继续处理下一行
            }

            // 构造Pinecone向量条目（一个Map）
            Map<String, Object> vectorEntry = new HashMap<>();
            // 设置唯一ID，格式为"no_行号"
            vectorEntry.put("id", "no_" + lineNum);
            // 设置向量值
            vectorEntry.put("values", vector);

            // 构造元数据（包含关键词和来源列信息）
            Map<String, String> metadata = new HashMap<>();
            metadata.put("column", map.get("key_column").toString().trim());
            metadata.put("word", map.get("key_word").toString().trim());
            // 将元数据添加到向量条目中
            vectorEntry.put("metadata", metadata);

            // 将构造好的向量条目添加到批次中
            batch.add(vectorEntry);
            lineNum++; // 行号递增

            // 当批次大小达到50时，执行批量上传
            if (batch.size() >= 50) {
                upsertToPinecone(batch, pineconeIndexKey, pineconeKey);
                successCount += batch.size(); // 更新成功计数
                batch.clear(); // 清空批次，准备下一批
            }
        }

        // 处理剩余的数据（不足50条的部分）
        if (!batch.isEmpty()) {
            upsertToPinecone(batch, pineconeIndexKey, pineconeKey);
            successCount += batch.size();
        }

        // 打印上传结果统计信息
        System.out.println("上传完成，共处理 " + lineNum + " 行");
        System.out.println("成功上传：" + successCount);
        System.out.println("失败上传：" + failedCount);
    }


    // 将向量数据上传至Pinecone向量库
    private static void upsertToPinecone(List<Map<String, Object>> vectors, String pineconeIndexKey, String pineconeKey) {
        // 创建可关闭的HTTP客户端实例（使用try-with-resources自动关闭）
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            // 创建POST请求，目标URL为Pinecone索引的API端点
            HttpPost httpPost = new HttpPost(pineconeIndexKey);
            // 设置请求头，指定内容类型为JSON
            httpPost.setHeader("Content-Type", "application/json");
            // 设置认证头，包含Pinecone API密钥
            httpPost.setHeader("Api-Key", pineconeKey);

            // 构造JSON请求体
            Map<String, Object> requestBody = new HashMap<>();
            // 设置向量列表
            requestBody.put("vectors", vectors);
            // 设置命名空间（固定为"default"）
            requestBody.put("namespace", "default");

            // 将请求体Map序列化为JSON字符串
            String jsonBody = OBJECT_MAPPER.writeValueAsString(requestBody);

            // 设置请求实体，并显式指定UTF-8编码（确保中文等字符正确传输）
            httpPost.setEntity(new StringEntity(jsonBody, StandardCharsets.UTF_8));

            // 执行HTTP请求并获取响应（使用try-with-resources自动关闭响应）
            try (CloseableHttpResponse response = httpClient.execute(httpPost)) {
                // 从响应中提取内容字符串
                String responseString = EntityUtils.toString(response.getEntity());
                // 打印Pinecone的响应信息（用于调试和监控）
                System.out.println("Pinecone upsert response: " + responseString);
            }
        } catch (Exception e) {
            // 捕获并打印异常堆栈信息
            e.printStackTrace();
        }
    }
}